package cl.zeke.pizzastore.vista.security;

import cl.zeke.java.commons.util.CodecUtil;
import cl.zeke.pizzastore.negocio.entities.Cliente;
import cl.zeke.pizzastore.negocio.entities.Perfil;
import cl.zeke.pizzastore.negocio.entities.Usuario;
import cl.zeke.pizzastore.negocio.services.UsuarioService;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationManager implements AuthenticationManager {
    
    private static Logger log = LoggerFactory.getLogger(CustomAuthenticationManager.class);
    
    @Autowired
    private UsuarioService usuarioService;
    
    @Autowired
    private Identidad identidad;
    
    @Override
    public Authentication authenticate(Authentication auth) throws AuthenticationException {
        log.debug("proceso de identificación. ");
        
        String email = auth.getName();
        String passwordPlana = auth.getCredentials().toString();
        String password = CodecUtil.generarHash(CodecUtil.TypeHash.MD5, passwordPlana);
        
        Usuario usuario = usuarioService.traerUsuarioConPerfilesPorEmailYPassword(email, password);
        
        if(usuario == null) {
            throw new AuthenticationServiceException("email o contraseña incorrectas");
        }
        
        if(!usuario.getActivo()) {
            throw new DisabledException("Usuario deshabilitado");
        }
        
        //traer cliente asociado
        Cliente cliente = usuarioService.traerClientePorUsuario(usuario);
        if(cliente == null) {
            cliente = new Cliente();
            cliente.setIdUsuario(usuario);
        }
        
        //carga de roles spring
        List<GrantedAuthority> roles = new ArrayList<>();
        for(Perfil p : usuario.getPerfilList()) {
            roles.add(new SimpleGrantedAuthority(p.getNombre()));
        }
        
        //carga de identidad
        identidad.iniciar(cliente);
        
        return new UsernamePasswordAuthenticationToken(
                auth.getName(),
                auth.getCredentials(),
                roles);
    }

}
